// @HEADER
//*********************************************************************//
//  SiYuan: A numerical PDE solver                                     //
//  Copyright (2022) YUAN Xi                                           //
//  This Software is released under the BSD 2-Clause license detailed  //
//  in the file "LICENSE" in the top-level SiYuan directory            //
//*********************************************************************//
// @HEADER

#include "Teuchos_Array.hpp"	
#include "Teuchos_ParameterEntryXMLConverterDB.hpp"
#include "Teuchos_XMLParameterListCoreHelpers.hpp"
#include "MaterialBase.hpp"
//#include "../misc/Registry.hpp"

namespace SiYuan
{
   Material::Material(const Teuchos::ParameterList& params)
   {
      for(auto it = params.begin(); it != params.end(); ++it) {
         if( it->first=="Name" ) continue;       // not a sublist
         auto pl = params.sublist(it->first);
         items[it->first] = std::make_shared<XYZLib::variable<double>>(pl);
      }
   }

   Material::Material(const std::string& name, const Teuchos::ParameterList& p)
   {
      for (auto it=p.begin(); it!= p.end(); ++it) {
         TEUCHOS_TEST_FOR_EXCEPTION( !(it->second.isList()), std::logic_error,
				"Error - All objects in the Material sublist must be unnamed sublists!" );
         Teuchos::ParameterList& sublist = Teuchos::getValue<Teuchos::ParameterList>(it->second);
    
         std::string matl_name = sublist.get<std::string>("Name");
         if( matl_name!=name ) continue;

         for(auto itm = sublist.begin(); itm != sublist.end(); ++itm) {
            if( itm->first=="Name" ) continue;       // not a sublist
            auto pl = sublist.sublist(itm->first);
            items[itm->first] = std::make_shared<XYZLib::variable<>>(pl);
         }
         return;
      }

      std::cout << "Cannot find Material " << name << std::endl;
      throw std::runtime_error("Error in Material construction!");
   }

   void
   Material::print(std::ostream& os) const
   {
      for(auto itr = items.begin(); itr != items.end(); ++itr) {
         os << "    Property Name = " << itr->first << std::endl;
      }
   }

   void 
   buildMaterials(CMaterials& materials,const Teuchos::ParameterList& p)
   {
      materials.clear();
      for (auto it=p.begin(); it!= p.end(); ++it) {
         TEUCHOS_TEST_FOR_EXCEPTION( !(it->second.isList()), std::logic_error,
				"Error - All objects in the Material sublist must be unnamed sublists!" );
         Teuchos::ParameterList& sublist = Teuchos::getValue<Teuchos::ParameterList>(it->second);
    
         std::string matl_name = sublist.get<std::string>("Name");
         materials[matl_name] = std::make_shared<Material>(sublist);
      }
   }

   void 
   printMaterials(CMaterials& materials,std::ostream& os)
   {
      for(auto itr = materials.begin(); itr != materials.end(); ++itr) {
         os << "--Material Name = " << itr->first << "--" << std::endl;
         itr->second->print(os);
      }
   }
  

  /* Elastic::Elastic()
   {};
	
   REGISTER_SUBCLASS(MaterialBase, Elastic, Elastic::create);

   REGISTER_SUBCLASS(MaterialBase, OrthotropicElastic, OrthotropicElastic::create);*/
} // End of namespace

